import React from 'react';
import QS from 'qs';
import axios from 'axios';
import { message, Modal } from 'antd';
import { isInIcestark } from '@ice/stark-app';
import { ExclamationCircleOutlined } from '@ant-design/icons';

const { confirm } = Modal;
message.config({
    prefixCls: 'hcp-message',
});

export const showTokenError = () => {
    Modal.destroyAll();
    confirm({
        prefixCls: 'hcp-modal',
        icon: <span className="iconfont iconfont-sm iconfont-yellow icon-confirm-warning" />,
        content: '登录失效，请重新登录!',
        okButtonProps: { prefixCls: 'hcp-btn' },
        cancelButtonProps: { prefixCls: 'hcp-btn', hidden: true },
        okText: '重新登录',
        onOk() {
            console.log(isInIcestark());
            console.log(window.ENV);
            if (isInIcestark() && !window.ENV.openLogin) {
                window.location.href = window.ENV.yunLiLogin;
            } else {
                window.location.href = '/login?status=10201';
            }
        },
        onCancel() {},
    });
};

export const getToken = () => {
    let token = '';
    const str = localStorage.getItem('_wocloud_storage_');

    if (str) {
        const obj = JSON.parse(str);
        if (obj.token && obj.token.value) {
            token = obj.token.value;
        }
    }
    return token;
};

axios.defaults.baseURL = window.ENV_CMDB.apiDomain;

const pending = {};
const CancelToken = axios.CancelToken;
const getRequestIdentify = (config, isReuest = false) => {
    let url = config.url;
    if (isReuest) {
        url = `${API_SERVER}/${config.url?.substring(1, config.url.length)}`;
    }
    return config.method === 'get'
        ? encodeURIComponent(url + JSON.stringify(config.params))
        : encodeURIComponent(config.url + JSON.stringify(config.data));
};
const removePending = (key, isRequest = false) => {
    if (pending[key] && isRequest) {
        pending[key]('取消重复请求');
    }
    delete pending[key];
};

axios.interceptors.request.use(
    (config) => {
        const token = getToken();
        if (token) {
            config.headers.ACCESS_TOKEN = token;
            config.headers.token = token;
            config.headers.Source = 'cmp';
        }
        //对中文进行编码
        if (config.headers.instanceName) {
            config.headers.instanceName = encodeURIComponent(config.headers?.instanceName);
        }
        if (config.headers.masterName) {
            config.headers.masterName = encodeURIComponent(config.headers?.masterName);
        }
        // 只针对get方式进行序列化
        if (config.method === 'get') {
            config.paramsSerializer = function (params) {
                return QS.stringify(params, { arrayFormat: 'repeat' });
            };
        }
        // 请求防抖
        let requestData = getRequestIdentify(config, true);
        removePending(requestData, true);
        // config.cancelToken = new CancelToken((c) => {
        //   pending[requestData] = c;
        // });
        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);

export default async function request(options) {
    try {
        const response = await axios(options);
        const res = response.data;
        if (response.request.responseType === 'arraybuffer') return res;
        if (response.request.responseType === 'blob') return response;

        if (res.status === '200' || res.code === 200 || res.code === 0 || res.code === 201) {
            return res;
        } else {
            const msg = res.message || res.msg || res.info;
            if (res.code === 1002 || res.code === 10201 || res.code === 10203) {
                if (isInIcestark()) {
                    return showTokenError();
                }
            }

            throw new Error(msg || '后端接口异常');
        }
    } catch (err) {
        message.destroy();
        // 统一处理接口异常逻辑
        if (err.response) {
            // 先报错，找不到msg再报状态
            message.error(err.response?.data?.msg || err.response.status);
            // message.error(err.response.status);
        } else if (err.request) {
            // Request was made but no response
            console.error(err.request);
        } else if (err.message === '取消重复请求') {
            console.log(`取消重复请求${JSON.stringify(options)}`);
        } else {
            message.error(err.message);
        }
        throw err;
    }
}

const instance = axios.create();

instance.interceptors.request.use(
    (config) => {
        const token = getToken();
        if (token) {
            config.headers.ACCESS_TOKEN = token;
        }
        // 只针对get方式进行序列化
        if (config.method === 'get') {
            config.paramsSerializer = function (params) {
                return QS.stringify(params, { arrayFormat: 'repeat' });
            };
        }
        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);

export async function requestIAM(options) {
    try {
        const response = await instance(options);
        const res = response.data;
        if (res.status === '200' || res.code === 200 || res.code === 0) {
            return res;
        } else {
            const msg = res.message || res.msg;
            if (res.code === 1002 || res.code === 10201 || res.code === 10203) {
                if (isInIcestark()) {
                    return showTokenError();
                }
            }
            throw new Error(msg || '后端接口异常');
        }
    } catch (err) {
        message.destroy();
        // 统一处理接口异常逻辑
        if (err.response) {
            message.error(err.response.status);
        } else if (err.request) {
            // Request was made but no response
            console.error(err.request);
        } else {
            message.error(err.message);
        }
    }
}

export async function exportFile(options, name) {
    try {
        // 资源模块列表导出添加pageNum、pageSize
        if (options.data && options.data.baseInfo) {
            options.data.baseInfo = {
                ...options.data.baseInfo,
                pageNum: 1,
                pageSize: 65536 || options.data.baseInfo.pageSize,
            };
        }
        const response = await axios({ ...options, responseType: 'blob' });

        const res = response;
        if (res.status != '200') {
            throw new Error(res.message || res.msg || '后端接口异常');
        }

        let fileName = name || '导出.xlsx';
        console.log('response.headers', response.headers);
        let cd = decodeURI(response.headers['content-disposition'] || response.headers['Content-Disposition']);
        if (fileName.indexOf('.json') > -1) {
            cd = encodeURIComponent(response.headers['content-disposition'] || response.headers['Content-Disposition']);
        }
        if (cd.indexOf('=') > -1) {
            fileName = cd.split('=')[1];
        }

        if (res) {
            const url = window.URL.createObjectURL(
                new Blob([res.data], {
                    type: res.data.type || 'application/vnd.ms-excel',
                })
            );
            const link = document.createElement('a');
            link.style.display = 'none';
            link.href = url;
            link.setAttribute('download', `${fileName}`);
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        } else {
            throw new Error(res.message || res.msg || '后端接口异常');
        }
    } catch (err) {
        // 统一处理接口异常逻辑
        if (err.response) {
            message.error(err.response.status);
        } else if (err.request) {
            // Request was made but no response
            console.error(err.request);
        } else {
            message.error(err.message);
        }
    }
}

export async function download(options, name) {
    try {
        const response = await axios({ ...options, responseType: 'blob' });
        const res = response.data;
        const fileName = name || decodeURI(response.headers['content-disposition'].split('=')[1]);
        const fileType = response.headers['content-type'].split(';')[0];

        if (res) {
            const url = window.URL.createObjectURL(
                new Blob([res], {
                    type: fileType,
                })
            );
            const link = document.createElement('a');
            link.style.display = 'none';
            link.href = url;
            link.setAttribute('download', `${fileName}` || '');
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    } catch (err) {
        // 统一处理接口异常逻辑
        if (err.response) {
            message.error(err.response.status);
        } else if (err.request) {
            // Request was made but no response
            console.error(err.request);
        } else {
            message.error(err.message);
        }
    }
}

export const requestUploadXhr = async ({
    url,
    method = 'post',
    data,
    headers = {},
    onProgress = (e) => e,
    getXhr,
    responseType,
    resHeaders = [],
}) => {
    return new Promise((resolve, reject) => {
        if (!url) reject('未传地址');
        const xhr = new XMLHttpRequest();
        // 暴露当前 xhr 给外部
        typeof getXhr == 'function' && getXhr(xhr);
        xhr.upload.onprogress = onProgress;
        xhr.open(method, url);
        if (responseType) xhr.responseType = responseType;
        Object.keys(headers).forEach((key) => xhr.setRequestHeader(key, headers[key]));
        xhr.send(data);
        xhr.onloadend = (e) => {
            if (!/^20/.test(e.target.status)) {
                reject(e.target.response);
            }
            let h = {};
            resHeaders.forEach((i) => {
                h[i] = xhr.getResponseHeader(i);
            });
            resolve({
                data: e.target.response,
                resHeaders: h,
            });
        };
    });
};
